#pragma once

#include "../../../Libs/headers.default.h"
#include "../../../Libs/headers.cv.h"
#include "../../../Libs/headers.classification.h"
#include "../../../Libs/headers.ipfe.h"
#include "../../../Libs/headers.ipfe_tools.h"
#include "../../../Libs/headers.and_or_tree.h"

#include "HiBoost.Instance.h"

using namespace loirey;
using namespace binary_ipfe_classification;

namespace hi_boost
{
	class CHiBoostExampleSettings
	{
	public:
		int NodeAmount;
		//int PosShakeAmount;
		CBicExampleConfig LargeBicExampleConfig;
		CSimpleTypeArray<CBicExampleConfig> List_PerNodeBicExampleConfig;
		CSimpleTypeArray<double> List_PerNodeFeatureContextCell_W;
		CSimpleTypeArray<double> List_PerNodeFeatureContextCell_H;

	public:
		void myInit(string strFN_HiBoostExampleSettings, int NodeAmount);
		CBicExampleConfig& GetNodeBicExampleConfig(int NodeIndex);
		const CBicExampleConfig& GetNodeBicExampleConfig(int NodeIndex) const;
		void GetNodeFeatureContextSettings(double& Context_W, double& Context_H, double& Cell_W, double& Cell_H, int NodeIndex) const;
	public:
		double ComputeGeneralIplScale(const CHiBoostNodeInstanceBoxSet* pSrcInstance) const;
	};
};

class CHiBoostGroundTruthList;

namespace hi_boost
{
	class CGlobalHiBoostSettings
	{
	public:
		and_or_tree::CAbstractTree AbstractTree;
		CHiBoostExampleSettings HiBoostExampleSettings;
	public:
		int Amount_SrcImage_Train_Pos;
		int Amount_SrcImage_Train_Neg;
		int Amount_SrcImage_Test_Pos;
		int Amount_SrcImage_Test_Neg;
		int Amount_Original_Annotation_Train;
		int Amount_Original_Annotation_Test;
		string strPN_SrcImage_Train_Pos;
		string strPN_SrcImage_Train_Neg;
		string strPN_SrcImage_Test_Pos;
		string strPN_SrcImage_Test_Neg;
		string strPN_INRIA_Annotation_Train;
		string strPN_INRIA_Annotation_Test;
		string strPN_Original_Annotation_Train;
		string strPN_Original_Annotation_Test;
	public:
		int Amount_GT_Annotation_Train;
		int Amount_GT_Annotation_Test;
		string strPN_Base_GT_Annotation;
		string strPN_Base_CropCT;
	public:
		int FileSetTag_for_BicParentFileName;
	public:
		string strFN_SelectedNodeList;
		string strFN_Original_Annotation_IgnoreList;
	public:
		string strPN_ExampleList;
		string strPN_Base_DrawExample;
		string strPN_Base_BoostModel;
		string strPN_Base_BoostDetect;
	public:
		string strPN_Perceptron_ImageCache;
	public:
		string strFN_Perceptron_ModelForDetect;
		string strPN_Perceptron_DetectBase;
		string strPN_Perceptron_ParseLog_Detect;

	public:
		const char* GetText_ImageSet(int sgnImageSet) const;
		const char* GetText_PosNeg(int sgnPosNeg) const;
	public:
		int GetAmount_SrcImage(int sgnImageSet, int sgnPosNeg) const;
		int GetAmount_GT_Annotation(int sgnImageSet) const;
		int GetAmount_Original_Annotation(int sgnImageSet) const;
	public:
		string GetPN_SrcImage(int sgnImageSet, int sgnPosNeg) const;
		string GetPN_Original_Annotation(int sgnImageSet) const;
		string GetPN_GT_Annotation(int sgnImageSet) const;
		string GetPN_GT_AnnExample(int sgnImageSet) const;
		string GetPN_CropCT(int NodeIndex, int sgnImageSet) const;
		string GetPN_DrawExample(int NodeIndex, int sgnImageSet) const;
		string GetPN_BoostModel(int NodeIndex) const;
		string GetPN_BoostDetect_SingleNode(int NodeIndex) const;
		string GetPN_PerceptronDetect_SingleNode(int NodeIndex) const;
		string GetPN_PerceptronDetect_ParseLog(int sgnImageSet, int sgnPosNeg, int ImageIndex, int LayerIndex) const;
	public:
		string GetPerceptronImageHashName(int sgnImageSet, int sgnPosNeg, int ImageIndex) const;
	public:
		void MakeFN_SrcImage(char* DstPtrChar, int sgnImageSet, int sgnPosNeg, int FileIndex) const;
		void MakeFN_INRIA_Annotation(char* DstPtrChar, int sgnImageSet, int FileIndex) const;
		void MakeFN_Original_Annotation(char* DstPtrChar, int sgnImageSet, int FileIndex) const;
		void MakeFN_Original_Ann__Image(char* DstPtrChar, int sgnImageSet, int FileIndex) const;
		void MakeFN_GT_Annotation(char* DstPtrChar, int sgnImageSet, int FileIndex) const;
		void MakeFN_GT_AnnExample(char* DstPtrChar, int sgnImageSet, int FileIndex) const;
		void MakeFN_CropGT(char* DstPtrChar, int NodeIndex, int sgnImageSet, int FileIndex) const;
		void MakeFN_ExampleList(char* DstPtrChar, int NodeIndex, int sgnImageSet) const;
		void MakeFN_DrawExample(char* DstPtrChar, int NodeIndex, int sgnImageSet, int ExampleIndex) const;
		void MakeFN_BoostModel(char* DstPtrChar, int NodeIndex) const;
		void MakeFN_BoostTrainLog(char* DstPtrChar, int NodeIndex) const;
		void MakeFN_BoostTestROC(char* DstPtrChar, int NodeIndex) const;

	public:
		int GetBicParentFileNameSetIndex(int sgnImageSet, int sgnPosNeg, bool fIsCropGT) const;
		void GenerateList_BicParentFileNameSet(CSimpleTypeArray<CBicExampleParentFileNameSet>& DstList_BicParentFileNameSet, int NodeIndex) const;
		void MakeGroundTruthSet(CHiBoostGroundTruthList& GT_List_Train, CHiBoostGroundTruthList& GT_List_Test) const;
	};

	extern CGlobalHiBoostSettings GlobalHiBoostSettings;
};

class CHiBoostNodeSetAppearanceIPFE
{
public:
	static int s_IFB_ImageExtent;
	static double s_IFB_TextonSigma;
	static const and_or_tree::CAbstractTree* s_pTree;
	static CSimpleTypeArray<CShapePatternList> s_SPL_List_A; 
	static CSimpleTypeArray<CShapePatternList> s_SPL_List_B; 
	static CSimpleTypeArray<CShapePatternList> s_SPL_List_C; 
	static CSimpleTypeArray<CShapePatternList> s_SPL_List_D; 
	static string s_strPN_IFB_Cache;
public:
	CShapePatternList CurrentSPL_A;
	CShapePatternList CurrentSPL_B;
	CShapePatternList CurrentSPL_C;
	CShapePatternList CurrentSPL_D;
	CImagePositionFeatureExtractor* pIPFE;
public:
	CImageFilterBank* pPrototypeIFB;
public:
	int Last_nsa_NodeIndex;

public:
	CHiBoostNodeSetAppearanceIPFE();
	~CHiBoostNodeSetAppearanceIPFE();
public:
	void InitIFB_A();
	void InitIFB_B();
	void InitIPFE_A();
public:
	void InitIFB_C();
	void InitIPFE_B();
public:
	void InitIFB_D();
	void InitIPFE_C();
public:
	void InitIPFE_D();
public:
	void InitIPFE_E();
public:
	void InitIPFE_F();
public:
	CImagePositionFeatureExtractor* GetNodeAppearnceIPFE(int NodeIndex);
};

//class CHiBoostExample
//{
//public:
//	double real_x, real_y;
//	double layer_scale_x, layer_scale_y;
//	bool fIsExamplePos;
//	bool fIsImagePos;
//	int FileIndex;
//
//public:
//	bool InputFromStream(istream& inStream);
//	void OutputToStream(ostream& outStream) const;
//};
//
//class CHiBoostExampleConfig
//{
//private:
//	bool __fPartSizesInitialized;
//public:
//	and_or_tree::CAbstractTree* pTree;
//	CHiBoostNodeContextConfig* pHiBoostNodeContextConfig;
//	string strPN_Base_CropGT;
//public:
//	int ObjectExtent, PartExtent;
//	int StdObjectBoundingBox_W, StdObjectBoundingBox_H;
//	double CropGT_xInferenceScale, CropGT_yInferenceScale;
//public:
//	int NodeAmount;
//public:
//	CSimpleTypeArray<double> PartCenterOffset_mx;
//	CSimpleTypeArray<double> PartCenterOffset_vx;
//	CSimpleTypeArray<double> PartCenterOffset_my;
//	CSimpleTypeArray<double> PartCenterOffset_vy;
//
//public:
//	CHiBoostExampleConfig();
//	void myInit(
//		and_or_tree::CAbstractTree* pFixedTree, CHiBoostNodeContextConfig* pFixedHiBoostNodeContextConfig,
//		int ObjectExtent, int PartExtent,
//		int StdObjectBoundingBox_W, int StdObjectBoundingBox_H,
//		double CropGT_xInferenceScale, double CropGT_yInferenceScale,
//		string strPN_Base_CropGT);
//public:
//	void MakeFN_PartCenterOffset(char* DstPtrChar) const;
//	void SavePartCenterOffset() const;
//	bool LoadPartCenterOffset();
//	void GetCenterByPart(
//		double& DstMX, double& DstMY, double& DstVX, double& DstVY,
//		double real_x, double real_y, double image_pyramid_layer_scale,
//		int NodeIndex) const;
//	//void GetCenterByPart(
//	//	double& DstMX, double& DstMY, double& DstVX, double& DstVY,
//	//	double real_x, double real_y, double scale_x, double scale_y,
//	//	int NodeIndex) const;
//public:
//	void GetStdPartContextSize(int& DstWidth, int& DstHeight, int NodeIndex) const;
//public:
//	static void AdjustImageLayerScale(double& xScale, double& yScale, int NodeIndex);
//public:
//	void ComputeParsedObject_ImageLayerScale(double& DstScale, const CHiBoostNodeInstanceBoxSet* pSrcParsedInstance) const;
//public:
//	void BuildGroundTruthExample(CHiBoostExample& DstExample, int NodeIndex, int FileIndex);
//	int AppendNegExamples(
//		CSimpleTypeArray<CHiBoostExample>& DstExampleList,
//		int PixelMargin, double PixelSampleRate,
//		int Image_W, int Image_H, int ScaleLevel, double ScaleFactor,
//		int NodeIndex, bool fAcceptBigImage,
//		int FileIndex, bool fIsImagePos);
//};
//
//class CDataSet_HiBoost_ByImage : public CLabeledDataSetForClassification
//{
//public:
//	CImagePyramidPositionFeatureExtractor* pIPPFE;
//	int NodeIndex;
//protected:
//	bool _fSharedIPPFE;
//protected:
//	int PosFileAmount;
//	int NegFileAmount;
//	const CSimpleTypeArray<string>* _pPosFileNameSet;
//	const CSimpleTypeArray<string>* _pNegFileNameSet;
//	string strFN_Pfx_ImageCacheHashName;
//
//	int _ImageHandle;
//	int _LastFileIndex, _LastNode;
//public:
//	int ExampleAmount;
//	CSimpleTypeArray<CHiBoostExample> ExampleList;
//public:
//	int DrawContext_W;
//	int DrawContext_H;
//	int DrawContext_Extent;
//
//public:
//	CDataSet_HiBoost_ByImage();
//	~CDataSet_HiBoost_ByImage();
//public:
//	void InitIPPFE(int NodeIndex, CImagePositionFeatureExtractor* pPrototypeIPFE, int CacheSize = 1);
//	void InitIPPFE(int NodeIndex, CImagePyramidPositionFeatureExtractor* pInitializedIPPFE, bool fShared);
//public:
//	void InitExampleList(
//		string strFN_ExampleList, string strFN_Pfx_ImageCacheHashName,
//		const CSimpleTypeArray<string>* pPosFileNameSet, const CSimpleTypeArray<string>* pNegFileNameSet
//		);
//	void InitDrawContextSettings(int W, int H, int Extent);
//public:
//	void SetQuery(int NodeIndex);
//	double GetFeature(int FeatureIndex);
//	void DrawExample(CImg<int>& imgDst);
//public:
//	int GetFeatureDimension();
//	int GetNodeAmount();
//	int GetNodeLabel(int NodeIndex);
//	double GetNodeInitialWeight(int NodeIndex);
//	double GetNodeFeature(int NodeIndex, int FeatureIndex);
//public:
//	virtual size_t GetMemoryUsage() const;
//};

class CHiBoostGroundTruthList
{
public:
	const hi_boost::CHiBoostExampleSettings* pExampleSettings;
	//const CHiBoostExampleConfig* pHiBoostExampleConfig;
	int Amount_SrcImage_Pos;
	CSimpleTypeArray<string> List_strFN_SrcImage_Pos;
	CSimpleTypeArray<string> List_strSrcImageHashName;
	int Amount_GroundTruth;
	CSimpleTypeArray<CHiBoostGroundTruth> GroundTruthList;
	CSimpleTypeArray<double> BaseImageLayerScaleList;

public:
	bool GetGroundTruth(CHiBoostGroundTruth& DstGroundTruth, CImg<int>& DstSourceImage, int GroundTruthIndex, double MinimalAcceptableImageLayerScale) const;
};

